﻿using System;
using GeoAPI.Geometries;
using NetTopologySuite.Geometries;

namespace NetTopologySuite.Algorithm.Distance
{
	public static class DistanceToPoint
	{
		public static void ComputeDistance(IGeometry geom, Coordinate pt, PointPairDistance ptDist)
		{
			if (geom is ILineString)
			{
				DistanceToPoint.ComputeDistance((ILineString)geom, pt, ptDist);
				return;
			}
			if (geom is IPolygon)
			{
				DistanceToPoint.ComputeDistance((IPolygon)geom, pt, ptDist);
				return;
			}
			if (geom is IGeometryCollection)
			{
				IGeometryCollection geometryCollection = (IGeometryCollection)geom;
				for (int i = 0; i < geometryCollection.NumGeometries; i++)
				{
					DistanceToPoint.ComputeDistance(geometryCollection.GetGeometryN(i), pt, ptDist);
				}
				return;
			}
			ptDist.SetMinimum(geom.Coordinate, pt);
		}

		public static void ComputeDistance(ILineString line, Coordinate pt, PointPairDistance ptDist)
		{
			Coordinate[] coordinates = line.Coordinates;
			LineSegment lineSegment = new LineSegment();
			for (int i = 0; i < coordinates.Length - 1; i++)
			{
				lineSegment.SetCoordinates(coordinates[i], coordinates[i + 1]);
				Coordinate p = lineSegment.ClosestPoint(pt);
				ptDist.SetMinimum(p, pt);
			}
		}

		public static void ComputeDistance(LineSegment segment, Coordinate pt, PointPairDistance ptDist)
		{
			Coordinate p = segment.ClosestPoint(pt);
			ptDist.SetMinimum(p, pt);
		}

		public static void ComputeDistance(IPolygon poly, Coordinate pt, PointPairDistance ptDist)
		{
			DistanceToPoint.ComputeDistance(poly.ExteriorRing, pt, ptDist);
			for (int i = 0; i < poly.NumInteriorRings; i++)
			{
				DistanceToPoint.ComputeDistance(poly.GetInteriorRingN(i), pt, ptDist);
			}
		}
	}
}
